<?php
/**
 * 自定义的控制器基类
 *
 * @final
 * @package Crmlite_Controller
 * @version $Id: Action.php 62 2007-09-10 06:40:30Z etng2004 $
 * @copyright 2006-2007 ETE.CN
 * @author Yi BO  <etng2004@gmail.com>
 * @license PHP Version 3.0 {@link http://www.php.net/license/3_0.txt}
 */

/** Zend_Controller_Action */
require_once "Zend/Controller/Action.php";

abstract class Crmlite_Controller_Action extends Zend_Controller_Action
{
	/**
     * Zend View
     *
     * @var Zend_View
     */
	public $view;
	/**
     * Configuration
     *
     * @var Zend_Config_Ini
     */
	public $config;
	/**
     * Cache
     *
     * @var Zend_Cache_Core
     */
	public $cache = null;
    /**
     * Session
     *
     * @var Zend_Session_Namespace
     */
    public $session = null;
	/**
	 * 脚手架模式，用于生成基本的程序架构
	 *
	 * @var boolean
	 */
	protected $scaffholding = false;
	/**
	 * 默认的模型
	 *
	 * 未初始化时是字符串，初始化之后就是一个模型接口
	 *
	 * @var Crmlite_Model
	 */
	protected $model = '';
	public $wwwroot;
	public $viewSuffix = 'php';

	public $module = "";
	public $controller = "";
	public $module_url='';
	public $base_url='';

	public $page = array();
	public $path = array();

	/**
     * Initialize object
     *
     * Called from {@link __construct()} as final step of object instantiation.
     *
     * @return void
     */
	public function init()
	{
		$this->config	= Zend_Registry::get('config');
		$this->cache	= Zend_Registry::get('cache');
		$this->view		= $this->initView();
		$this->getResponse()->setHeader('Content-Type', 'text/html; charset=' . $this->config->view->encoding);
		$this->view->addHelperPath(LIB_DIR . '/Crmlite/View/Helper', 'Crmlite_View_Helper');
		$this->view->controller = $this;
		$this->initUrls();
		$this->initPages();
		$this->session = new Zend_Session_Namespace($this->module);
		/**
		 * 加载默认模型
		 */
		if($this->model && is_string($this->model))
		{
			$model_class = $this->model . 'Model';
			$this->model = new $model_class();
		}
	}
	protected function setTitle($title, $count = null, $meta = array())
	{
		$this->path['node'] = array('title' => $title);
		is_null($count) || $this->path['node']['count'] = $count;
		$this->page = array_merge($this->page, $meta);
	}
	protected function pushPoint($title, $url = null )
	{
		!is_null($url) || $url = $this->base_url;
		$this->path['points'][] = array('title'=>$title, 'link'=>$url);
	}
	public function initPages()
	{
		$this->page = array(
		'title'=>'CRMLite.cn Beta',
		'keywords'=>'CRMLite,CRM,客户关系管理,中小企业，渠道，市场',
		'description'=>'CRMLite 是一款针对中小企业开发的客户关系管理系统(CRM)，通过他你可以管理你的渠道、市场，还可以对内部员工的工作起到侦查和监视的作用。',
		'version'=>'0.0.9',
		);
		$this->page = array_merge($this->page, $this->config->site->toArray());
		$this->path = array(
		'root'=>array('link'=>'/', 'title'=>'首页'),
		'points'=>array(),
		'node'=>array('title'=>''),
		);
	}
	/**
	 * Default view if no action is requested.
	 */
	public function indexAction()
	{
		if($this->scaffholding)
		{
			$this->_forward('generator');
		}
	}
    /**
     * Default captcha Action
     *
     */
    public function captchaAction()
    {
  		/**
    	 * WE do not need render from template!
    	 */
    	$this->_helper->viewRenderer->setNoRender();
    	$Captcha = new Crmlite_Captcha();
        $this->session->captcha = $Captcha->getCode();
        $Captcha->show();
    }

	/**
	 * 代码生成器
	 *
	 */
	public function generatorAction()
    {
    	/**
    	 * WE do not need render from template!
    	 */
    	$this->_helper->viewRenderer->setNoController();
    	if(!$this->scaffholding)
    	{
    		$this->log($msg = "SCAFFHOLDING is disabled");
    		exit($msg);
    	}
    	if(is_null($this->model))
    	{
    		$this->log($msg = "INVALID Model FOR SCAFFHOLDING");
    		exit($msg);
    	}
    	$script_path = dirname($this->view->getScriptPath($this->getRequest()->getActionName()));
    	$controller_path = $this->getFrontController()->getControllerDirectory($this->module);
    	if($this->isPost())
    	{
    		$overwrite = isset($_POST['fields']['options']['overwrite']);
    		$this->log("Begin Write Generated views!");
    		foreach ($_POST['fields']['scripts'] as $k => $v)
    		{
				$real_path = str_replace('\\', '/', $script_path) . '/' . $v['filename'];
				$this->log($msg = "Saving File {$v['filename']} To Folder {$script_path}");
				if(file_exists($real_path))
				{
					if($overwrite)
					{
						$this->log("File Exists!Overwrited!");
					}
					else
					{
						$this->log("File Exists!Aborted!");
						continue;
					}
				}
				$this->log($real_path);
				file_put_contents($real_path, $v['content']);
     		}
    		$this->log("End Write Generated views!");
    		$this->log("Begin Write Generated Controller!");
    		$v_controller = $_POST['fields']['controller'];
    		$real_path = str_replace('\\', '/', $controller_path) . '/' . $v['filename'];
			$this->log($msg = "Saving File {$v['filename']} To Folder {$controller_path}");
				if(file_exists($real_path))
				{
					if($overwrite)
					{
						$this->log("File Exists!Overwrited!");
					}
					else
					{
						$this->log("File Exists!Aborted!");
						continue;
					}
				}
				$this->log($real_path);
				file_put_contents($real_path, $v['content']);
    		$this->log("End Write Generated Controller!");
    		echo "Finished!";
    		exit();
    	}
    	$Model = $this->model;
    	/* @var $Model Crmlite_Model */
    	$info = $Model->info();
    	$this->view->meta = $info;
    	$this->view->module = $this->module;
    	$this->view->controller = $this->controller;
    	$this->view->scripts_path = $script_path;
    	$this->view->controller_path = $controller_path;
    	$this->setTitle('代码生成器');
    }
	/**
	 * 控制器内部的事件记录
	 *
	 * @param string $msg	消息
	 * @param int $level	等级
	 */
	protected function log($msg, $level = Zend_Log::DEBUG )
	{
		Crmlite_App::log( get_class($this) . '[IN_ACTION]' . $msg, $level);
	}
	/**
	 * 查询改请求的历史地址，直接返回改地址
	 *
	 * @param string $default  默认地址
	 * @param string $request  请求的其他Moule_Controller_Action 的覆盖值，在转向其他页时有用
	 * @return string
	 */
	protected function getHistory($default = null, $request = array())
	{
		$default_request = array(
		'action'      => $this->getRequest()->getActionName(),
		'controller'  => $this->getRequest()->getControllerName(),
		'module'      => $this->getRequest()->getModuleName(),
		);
		$request = array_merge($default_request, $request);
		return Crmlite_History::get($request['controller'], $request['action'], $request['module'], $default);
	}
    /**
     * 保存当前请求历史地址
     *
     * @param string $url
     */
	protected function saveHistory($url = null)
	{
		$request = $this->getRequest();
		/* @var $request Zend_Controller_Request_Abstract*/
		return Crmlite_History::save($request->getControllerName(), $request->getActionName(), $request->getModuleName(), $url);
	}
	/**
	 * Error 404 if there is an undefined action.
	 */
	public function __call($action, $arguments)
	{
		$this->log("ACTION {$action} MISSED! With Arguments:" . var_export($arguments, true), Zend_Log::ERR);
		header('HTTP/1.1 404 Not found');
		exit("<blockquote><h1>NOT FOUND</h1>The requested URL ". $_SERVER['REQUEST_URI'] ." was not found on this server.</blockquote>");
	}

	public function postDispatch()
	{

		$this->showDebugInfo();
	}

	/**
	 * Debug 相应信息
	 *
	 */
	protected function showDebugInfo()
	{
	    if(!$this->config->General->debug)return false;
		$Profiler = Zend_Registry::get('db')->getProfiler();
		/* @var $Profiler Zend_Db_Profiler */
		$debug = array();
		if($debug['db']['enabled'] =  $Profiler->getEnabled())
		{
			$debug['db'] = array(
			'enabled' 		=> true,
			'total_time' 	=> $Profiler->getTotalElapsedSecs(),
			'total_query' 	=> $Profiler->getTotalNumQueries(),
			'longest_time' 	=> 0,
			'longest_query' => null,
			'queries' 		=> array(),
			);

			foreach ($Profiler->getQueryProfiles() as $Query)
			{
				/* @var $Query Zend_Db_Profiler_Query */
				$debug['db']['queries'][] = $Query->getQuery();
				if ($Query->getElapsedSecs() > $debug['db']['longest_time'])
				{
					$debug['db']['longest_time']  = $Query->getElapsedSecs();
					$debug['db']['longest_query'] = $Query->getQuery();
				}
			}
		}
		$this->view->debug = $debug;
	}
	/**
	 * 判断是否为POST请求
	 *
	 * @return boolean
	 */
	public function isPost()
	{
		return (strtolower($_SERVER['REQUEST_METHOD']) == 'post');
	}

	/**
	 * 根据系统的模块和请求的控制器，生成当前的base_url
	 *
	 */
	function initUrls()
	{
		$request = $this->getRequest();
		$this->module = $module = $request->getModuleName();
		$this->controller = $controller = $request->getControllerName();
		$this->view->wwwroot = $this->wwwroot = BASE_URL;
		if($module == 'default')
		{
			$module = '';
			$this->view->module_url = $this->module_url = $this->wwwroot;
		}
		else
		{
			$this->view->module_url = $this->module_url = $this->wwwroot . "/$module";
		}
		$this->view->base_url = $this->base_url = $this->module_url . "/$controller";
	}
	/**
     * Construct view script path
     *
     * Used by render() to determine the path to the view script.
     *
     * @param  string $action Defaults to action registered in request object
     * @param  bool $noController  Defaults to false; i.e. use controller name as subdir in which to search for view script
     * @return string
     * @throws Zend_Controller_Exception with bad $action
     */
	public function getViewScript($action = null, $noController = true)
	{
		if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) {
			$viewRenderer = $this->_helper->getHelper('viewRenderer');
			$viewRenderer->setNoController(true);
			return $viewRenderer->getViewScript($action);
		}
		$request = $this->getRequest();
		if (null === $action) {
			$action = $request->getActionName();
		} elseif (!is_string($action)) {
			throw new Zend_Controller_Exception('Invalid action specifier for view render');
		}

		if (null === $this->_delimiters) {
			$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
			$wordDelimiters = $dispatcher->getWordDelimiter();
			$pathDelimiters = $dispatcher->getPathDelimiter();
			$this->_delimiters = array_unique(array_merge($wordDelimiters, (array) $pathDelimiters));
		}

		$action = str_replace($this->_delimiters, '-', $action);
		$controller = $request->getControllerName();
		$controller = str_replace($this->_delimiters, '-', $controller);
		$script = $controller .'_'.$action . '.' . $this->viewSuffix;
		return $script;
	}
}